#-*- coding: utf-8 -*-

#This file is part of pyLot library.
#
# pyLot is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyLot is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with pyLot.  If not, see <http://www.gnu.org/licenses/>.

__author__ = u'Pierre Puiseux, Guillaume Baty'
__copyright__ = u"Copyright 2011-2012 (C) andheo, Université de Pau et des Pays de l'Adour"
__credits__ = [u'Pierre Puiseux', u'Guillaume Baty']
__license__ = "GNU Lesser General Public License"

from Qt4 import QtCore, QtGui

from pyLot.core import Container, Datum, ENCODING, PyLotDict
from _pylot.qtgui.widgets.gui_containereditor import GuiContainerEditor
from _pylot.qtgui.modelview import (GuiDatumTableView, GuiContainerTreeView,
                                    DatumModel, ContainerModel, Widget)

from traits.api import HasTraits

def impl_factory(widget, name=u'widget', alias=u'widget', **kargs):
  c = Container(name, alias=alias)
  lst = []
  for interface in widget.__implements__.getBases():
    lst += dir(interface)

  for i in lst :
    if i in dir(HasTraits) or i.startswith(u'_Protocol'):
      continue
    else :
      c.add(Datum(i.decode(ENCODING), bool, None, None, alias=i.decode(ENCODING)))

  return c

class GuiTestBox(QtGui.QDialog):
  u"""
  GuiTestBox provides a dialog to test a widget.
  
  GuiTestBox looks for all "_test_xxx" methods for widget_to_test widget and
  its associated handler.
  ..todo :: 
    
    If handler has a "test_suites" attributes, test suites are appended to 
    available tests.
  """

  def __init__(self, widget_to_test):
    QtGui.QDialog.__init__(self)

    self.wtest = widget_to_test
    self.layout_main = QtGui.QGridLayout(self)

    self._createTests()
    self._checkImplementation()

  def _checkImplementation(self):
    self.model_impl = ContainerModel()
    self.impl = Container(u'root')
    self.view_impl = GuiContainerTreeView(self.model_impl)
    self.layout_main.addWidget(self.view_impl, 0, 1)
    cpt = 0
    self._createImplCheck(self.container, self.impl, cpt)
    self.view_impl.fineTune()
    self.model_impl.addContainer(self.impl)
    self.view_impl.expandAll()
    self.view_impl.fineTune()

  def _createImplCheck(self, container, impl, cpt):
    widget = self.widgets[u'id_%s' % id(container)]
    subimpl = impl_factory(widget, name=container.name, alias=container.alias)

    for i in range(len(subimpl)):
      meth_name = subimpl[i].name
      try:
        meth = getattr(widget, meth_name)
      except AttributeError :
        subimpl[i].value = False
      else :
        subimpl[i].value = True

    impl.add(subimpl)
    for subc in container.iterContainerValues():
      cpt = self._createImplCheck(subc, subimpl, cpt)
    return cpt + 1


  def _createTests(self):
    self.widgets = PyLotDict()
    self.container = self.createTestContainer(self.wtest)

    self.view_tests = GuiContainerEditor(self.container)
#    self.model_tests = ContainerModel()
#    self.model_tests.addContainer(self.container)
#    self.view_tests = GuiContainerTreeView(self.model_tests)
#    self.view_tests.fineTune()

    self.layout_main.addWidget(self.view_tests, 0, 0)
    self.pb_run_tests = QtGui.QPushButton(u'Lancer les tests')
    self.layout_main.addWidget(self.pb_run_tests, 1, 0, 1, 2)

    self.pb_run_tests.clicked.connect(self.runTests)

  def createTestContainer(self, widget):
    if hasattr(widget, 'identifier'):
      alias = widget.identifier.decode(ENCODING)
      name = alias.replace(u'.', u'_')
    elif hasattr(widget, 'objectName') and widget.objectName():
      alias = unicode(widget.objectName())
      name = alias
    else :
      alias = unicode(widget.__class__)
      name = unicode(widget.__class__.__name__)

    container = Container(name, alias=alias)
    self.widgets[u'id_%s' % id(container)] = widget

    for fname in dir(widget):
      if fname.startswith(u'_test'):
        fname = fname.decode(ENCODING)
        f = getattr(widget, fname)
        alias = fname.replace(u'_test', u'')
        alias = alias.replace(u'_', u' ')
        datum = Datum(fname, bool, False, tooltip=f.__doc__, alias=alias)
        container.addDatum(datum)

    for subwidget in widget :
      subcontainer = self.createTestContainer(subwidget)
      container.addContainer(subcontainer)

    if hasattr(widget, 'handler'):
      subcontainer = self.createTestContainer(widget.handler)
      subcontainer.alias = subcontainer.alias.split(u'.')[-1]
      if subcontainer :
        container.addContainer(subcontainer)

    return container

  def runWidgetTest(self, container):
    widget = self.widgets[u'id_%s' % id(container)]
    for fname in container.iterDatumKeys():
      if container(fname):
        print
        print "-"*80
        print container[fname].alias
        print "*"*20
        f = getattr(widget, fname)
        f()
        print "-"*80

    for subcontainer in container.iterContainerValues():
      self.runWidgetTest(subcontainer)

  def runTests(self):
    self.runWidgetTest(self.container)


if __name__ == '__main__' :
  pass
